package com.itheima.log;


import com.alibaba.dubbo.config.annotation.Reference;
import com.alibaba.fastjson.JSON;
import com.itheima.pojo.Log;
import com.itheima.service.LogService;
import com.itheima.utils.IpUtil;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.User;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.util.Date;

@Component
@Aspect
public class LogAspect {
    @Reference
    private LogService logService;

    @Pointcut("execution(* com.itheima.web.*.*(..))")
    public void pointCut() {
    }
    @Around("pointCut()")
    public Object logAdvice(ProceedingJoinPoint pj) throws Throwable {
        User user = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        Log log = new Log();
        MethodSignature signature = (MethodSignature) pj.getSignature();
        Method method = signature.getMethod();
//        注解信息
        RequestMapping annotation = method.getAnnotation(RequestMapping.class);
        if (user != null) {
            log.setUsername(user.getUsername());
        }
        log.setMethod(JSON.toJSONString(annotation.value()));
//        ip地址
        log.setIp(IpUtil.getIpAddress(request));
        log.setCreateDate(new Date());
        Object object;
        try {
            Object[] args = pj.getArgs();
            log.setParams(JSON.toJSONString(args));
             object = pj.proceed();
            log.setResult(JSON.toJSONString(object));
        } catch (Throwable throwable) {
            throw throwable;
        }finally {
            logService.addLog(log);
        }
        return object;
    }
}
